Fork me on GitHub

JVM内存管理

注意:所有文章除特别说明外,转载请注明出处.

第八章 JVM内存管理

[TOC]

8.3 Java中内存使用组件

8.3.1 Java堆

Java堆是用来存储Java对象的内存区域,堆的大小在JVM启动时就一次向操作系统申请完成,通过-Xmx | -Xms两个选项控制大小。一旦分配完成那么堆的大小就固定,不能在内存不够时再向操作系统重新申请。不能在内存空闲时将多余的空间交还给操作系统。

-Xmx 表示堆的最大大小

-Xms 表示初始大小

提示:Java堆内存空间的管理由JVM控制,对象创建由Java应用程序控制,但是对象所占的空间释放由管理堆内存的垃圾收集器完成。

8.3.2 线程

JVM运行实际程序的实体是线程,线程需要内存空间存储一些必要的数据。每个线程创建时,JVM都会3为它创建一个堆栈。堆栈的大小由不同的JVM实现而不同。

8.3.3 类和类加载器

8.3.4 NIO

NIO类库,新加一种基于通道和缓冲区来执行I/O的新方式。就如同Java堆上的内存支持I/O缓冲区一样,NIO使用java.nio.ByteBuffer.allocateDirect()方法分配内存。

ByteBuffer.allocateDirect()分配的内存使用的是本机内存而不是Java堆上的内存。

8.3.5 JNI

JNI技术使得本机代码可以调用Java方法,也就是通常所说的native memory。在实际上Java运行时也依赖于JNI代码来实现类库功能,如:文件操作、网络IO操作或其它系统调用。

8.4 JVM内存结构

在Java虚拟机规范中将Java运行时数据划分为6种。

1. PC寄存器数据

    PC寄存器严格来说是一个数据结构,它用于保存当前正常执行的程序的内存地址。

2. Java栈

    Java栈总是与线程关联起来的,每当创建一个线程时,JVM就会给这个线程创建一个对应的Java栈,这个Java栈中又会含有多个栈帧,这些栈帧是与每个方法关联起来的,每运行一个方法就创建一个栈帧,每个栈帧都包含一些内部变量(在方法内定义的变量),操作栈和方法返回值等信息。

3. 堆

    堆是存储Java对象的地方,它是JVM管理Java对象的核心存储区域。

    注意:堆是被Java线程所共享的,所以对它的访问需要注意同步问题,方法和对应的属性都需要保证一致性。

4. 方法区

    Java方法区是用作存储类结构信息的地方,如:常量池、域、方法数据、方法体、构造函数。

    方法区又是堆中的一部分,是永久区。

5. 本地方法栈

    本地方法栈是为JVM运行Native方法准备的空间,与Java栈的作用类似。

6. 运行时常量池

8.5 JVM内存分配策略

8.5.1 通常内存分配策略

1. 静态内存分配

    表示程序在编译时能够确定每个数据在运行时刻的存储空间需求,所以在编译时能够为它们分配固定的内存空间。

2. 栈内存分配

    该内存分配又称动态内存分配,是类似于堆栈的运行栈实现。程序对数据区的需求在编译时未知,在运行时知道,在规定运行时进入程序模块时,必须知道程序模块所需的数据区大小才能为其分配内存。

3. 堆内存分配

    程序真正运行到相应代码时才会知道空间大小,这时候就需要堆内存分配策略。

8.5.2 Java内存分配

JVM内存分配主要基于两种,堆和栈。

Java栈的分配是与线程绑定在一起,在创建一个线程时,JVM会给该线程创建一个新的Java栈。在线程激活一个Java方法时,JVM就在线程的Java堆栈中新压入一个帧。帧存放当前方法在执行期间的参数、局部变量等。

栈中主要存放一些基本变量数据和对象句柄(引用)。

8.6 Java内存回收机制

8.6.1 静态内存分配与回收

由前面知道的静态内存分配,我们知道在静态内存空间是在Java栈上分配的,当这个方法运行结束时,对应的栈帧也就撤销,所以分配的静态内存空间也就回收了。

8.6.2 动态内存分配与回收

动态内存回收与垃圾回收机制有关。

8.7 内存问题分析

8.7.1 GC日志分析

GC日志输出如下参数:

1. -verbose:gc 辅助输出详细的GC信息

2. -XX:+PrintGCDetails 输出GC的详细信息

3. -XX:+PrintGCApplicationStoppedTime 输出GC造成应用程序暂停的时间

4. -XX:+PrintGCDateStamps GC发生的时间信息

5. -XX:+PrintHeapAtGC 在GC前后输出堆中各个区域的大小

6. -Xloggc:[file] 将GC信息输出到单独的文件中

本文标题:JVM内存管理

文章作者:Bangjin-Hu

发布时间:2019年10月15日 - 09:22:26

最后更新:2020年03月30日 - 08:15:47

原始链接:http://bangjinhu.github.io/undefined/第八章 JVM内存管理/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

Bangjin-Hu wechat
欢迎扫码关注微信公众号,订阅我的微信公众号.
坚持原创技术分享,您的支持是我创作的动力.